package com.zmn.oms.zmn.business.impl.work.autoflow.state;

import com.alibaba.fastjson.JSON;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.consts.GlobalConsts;
import com.zmn.dms.common.enums.DiscountTypeEnums;
import com.zmn.manager.mq.interfaces.ZmnMQSender;
import com.zmn.oms.business.interfaces.conf.channel.ConfOrderChannelBService;
import com.zmn.oms.business.interfaces.conf.checkout.ConfCheckoutBService;
import com.zmn.oms.business.interfaces.master.OrderMasterBService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.dro.conf.channel.ConfOrderChannelDRO;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.dto.work.modify.must.ZsCheckOutDTO;
import com.zmn.oms.model.entity.conf.checkout.ConfCheckout;
import com.zmn.oms.model.entity.conf.checkout.ConfCheckoutQuery;
import com.zmn.oms.model.entity.discount.OrderDiscount;
import com.zmn.oms.model.entity.serviceitem.OrderServiceItem;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.serviceitem.ServiceItemVO;
import com.zmn.oms.model.vo.work.OperatePermissionVO;
import com.zmn.oms.services.interfaces.discount.OrderDiscountService;
import com.zmn.oms.services.interfaces.serviceitem.OrderServiceItemService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkOperatePermissionBService;
import com.zmn.oms.zmn.business.interfaces.work.autoflow.state.WorkAutoFlowBService;
import com.zmn.oms.zmn.normal.business.interfaces.work.financework.ZsNormalFinanceWorkBService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * @author sunlife
 * @date:2020/9/23 6:41 下午
 * description:
 */
@Slf4j
@Service("flowCheckoutBService")
public class FlowCheckoutBServiceImpl<T> implements WorkAutoFlowBService<T> {

    @Autowired
    ZsNormalFinanceWorkBService zsNormalFinanceWorkBService;
    @Autowired
    ConfCheckoutBService confCheckoutBService;
    @Autowired
    ZsOrderWorkOperatePermissionBService zsOrderWorkOperatePermissionBService;
    @Autowired
    OrderMasterBService orderMasterBService;
    @Autowired
    OrderServiceItemService orderServiceItemService;
    @Autowired
    private OrderDiscountService orderDiscountService;
    @Resource
    ZmnMQSender zmnMQSender;
    @Resource
    private ConfOrderChannelBService confOrderChannelBService;

    private static final String AUTO_CHECKOUT_KEY = "%s-auto-checkout-%s";

    @Override
    public ResultDTO<T> condition(OrderWork orderWork) {
        /*if (Objects.equals(orderWork.getType(), OrderConsts.ORDER_TYPE_REFUND)) {
            return ResultDTO.fail("退款单不自动收单");
        }*/
        if (Objects.equals(orderWork.getStatus(), OrderStatusConsts.WORK_STATUS_CHECKOUT)) {
            return ResultDTO.fail("订单已收单");
        }

        // 渠道配置自动收单判断
        ConfOrderChannelDRO confOrderChannelDRO = null;
        try {
            confOrderChannelDRO = confOrderChannelBService.getByChannelId(orderWork.getChannelId());
        } catch (OmsBaseException omsBaseException) {
            omsBaseException.printStackTrace();
        }

        if (Objects.nonNull(confOrderChannelDRO) && Objects.equals(GlobalConsts.NO, confOrderChannelDRO.getAutoCollectOrder())) {
            log.info("ChannelOrderConfigDRO {}", JSON.toJSONString(confOrderChannelDRO));
            return ResultDTO.fail("渠道未设置自动收单");
        }

        // F端 & 服务完成状态
        if (Objects.equals(orderWork.getBizType(), GlobalConsts.BIZ_TYPE_F)) {
            if (!Objects.equals(orderWork.getStatus(), OrderStatusConsts.WORK_STATUS_COMPLETE)) {
                return ResultDTO.fail("非F端工单或不是已完成状态，不满足自动收单条件");
            } else {
                if ((Objects.equals(orderWork.getType(), OrderConsts.ORDER_TYPE_NEW) || Objects.equals(orderWork.getType(), OrderConsts.ORDER_TYPE_REWORK))
                        && Objects.equals(orderWork.getMultiMaster(), com.zmn.common.constant.GlobalConsts.YES)) {
                    boolean opMasterSharing = orderMasterBService.checkMasterSharing(orderWork);
                    if (!opMasterSharing) {
                        return ResultDTO.fail("工程师分润未设置，不可操作！");
                    }
                }
                return ResultDTO.success(orderWork);
            }
        }

        // 保留配件申请24小时，不自动流转
        if (Objects.equals(orderWork.getPartRetain(), GlobalConsts.YES)) {
            return ResultDTO.fail("保留配件申请24小时，完成后不自动收单");
        }

        //TODO sunlingfu 消息处理待商榷
        OperatePermissionVO permissionVO = zsOrderWorkOperatePermissionBService.getOperatePermission(orderWork, OrderConsts.ORDER_OP_TYPE_CHECKOUT, GlobalConsts.OPERATE_USER_TYPE_SYSTEM);
        if (!permissionVO.getCanOperate()) {
            return ResultDTO.fail(permissionVO.getMsg());
        }
        // 仓储检查权限
        OperatePermissionVO existsSCMToAuditPartsOPV = zsOrderWorkOperatePermissionBService.existsSCMToAuditParts(orderWork.getOrderId(), orderWork.getType());
        if (!existsSCMToAuditPartsOPV.getCanOperate()) {
            return ResultDTO.fail(existsSCMToAuditPartsOPV.getMsg());
        }
        return ResultDTO.success(orderWork);
    }

    @Override
    public void execute(T t) {
        OrderWork orderWork = (OrderWork)t;
        try {
            ZsCheckOutDTO checkOutDTO = new ZsCheckOutDTO();
            checkOutDTO.setOrderId(orderWork.getOrderId());
            checkOutDTO.setWorkId(orderWork.getWorkId());
            checkOutDTO.setOperator(com.zmn.common.constant.GlobalConsts.getOperatorTypeName(com.zmn.common.constant.GlobalConsts.OPERATE_USER_TYPE_SYSTEM));
            checkOutDTO.setOperatorId(Long.valueOf(com.zmn.consts.GlobalConsts.OPERATE_USER_TYPE_SYSTEM));
            checkOutDTO.setOperatorType(com.zmn.common.constant.GlobalConsts.OPERATE_USER_TYPE_SYSTEM);
            checkOutDTO.setAppliqueStatus(GlobalConsts.YES);
            checkOutDTO.setMasterImageStatus(GlobalConsts.YES);
            checkOutDTO.setIsAutoCheckOut(true);
            if (Objects.equals(orderWork.getType(), OrderConsts.ORDER_TYPE_NEW)) {
                List<OrderServiceItem> orderServiceItems = orderServiceItemService.listByOrderId(orderWork.getOrderId());
                List<ServiceItemVO> serviceItemVOS = BeanMapper.mapList(orderServiceItems, ServiceItemVO.class);
                for (ServiceItemVO serviceItemVO : serviceItemVOS) {
                    serviceItemVO.setOldInternalSettlementPrice(serviceItemVO.getInternalSettlementPrice());
                }
                checkOutDTO.setServiceItemVOList(serviceItemVOS);
            }

            // 计算结果状态
            ConfCheckoutQuery confCheckoutQuery = ConfCheckoutQuery.builder().plat(orderWork.getPlatWork())
                    .servCategId(orderWork.getServCategId())
                    .categOneId(orderWork.getCategOneId())
                    .categTwoId(orderWork.getCategId())
                    .status(GlobalConsts.YES).build();
            ConfCheckout checkOutConf = confCheckoutBService.getConfByQuery(confCheckoutQuery);
            // 订单金额
            Integer amount = orderWork.getOriginalAmount();
            if (Objects.equals(orderWork.getType(), OrderConsts.ORDER_TYPE_NEW)) {
                // 收单标准 if 有优惠 订单金额 - 优惠金额(只算人工优惠) else 订单金额
                List<OrderDiscount> orderDiscountList = orderDiscountService.listByOrderId(orderWork.getOrderId());
                if (CollectionUtils.isNotEmpty(orderDiscountList)) {
                    int artificialAmount = orderDiscountList.stream().filter(item -> Objects.equals(item.getCateg(), DiscountTypeEnums.DISCOUNT_RULE_ARTIFICIAL.getSubType()))
                            .mapToInt(OrderDiscount::getAmount).sum();
                    if (Objects.nonNull(amount) && NumberUtil.isNotNullOrZero(artificialAmount)) {
                        amount = amount - artificialAmount;
                    }
                }
            }
            if (Objects.isNull(checkOutConf.getAmount()) || (Objects.nonNull(amount) && amount >= checkOutConf.getAmount())) {
                checkOutDTO.setResultStatus(OrderStatusConsts.WORK_RESULT_SUCCESS);
            } else {
                checkOutDTO.setResultStatus(OrderStatusConsts.WORK_RESULT_FAIL);
            }

            zsNormalFinanceWorkBService.saveFacadeCheckOut(checkOutDTO);

        } catch (Exception e) {
            log.error("自动收单异常" + e.getMessage(), e);
        }

    }
}
